using ColorFillGame.Domain.Exceptions;
using ColorFillGame.Domain.ValueObjects;

namespace ColorFillGame.Domain.Entities;

public class Player : Entity
{
    public string Name { get; private set; }
    public Guid GameId { get; private set; }
    public PlayerColor? Color { get; private set; }
    public DateTime JoinedAt { get; private set; }
    public string? ConnectionId { get; set; }
    public bool Ready { get; private set; } = false;

    private Player()
    {
        // EF Core constructor
    }

    public Player(Guid id, string name, Guid gameId)
        : base(id)
    {
        Name = name;
        GameId = gameId;
        JoinedAt = DateTime.UtcNow;
    }

    public void SetColor(PlayerColor color)
    {
        Color = color;
    }

    public void UpdateName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new DomainException("Player name cannot be empty.");
        
        Name = name;
    }

    public void SetConnectionId(string connectionId)
    {
        ConnectionId = connectionId;
    }
    
    public void SetReadyStatus(bool ready)
    {
        Ready = ready;
    }
}

public abstract class Entity
{
    public Guid Id { get; protected set; }

    protected Entity(Guid id)
    {
        Id = id;
    }

    protected Entity()
    {
        // EF Core constructor
        Id = Guid.NewGuid();
    }

    public override bool Equals(object? obj)
    {
        if (obj is not Entity other)
            return false;
        
        return Id == other.Id;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public static bool operator ==(Entity? left, Entity? right)
    {
        if (left is null && right is null)
            return true;
        
        if (left is null || right is null)
            return false;
        
        return left.Equals(right);
    }

    public static bool operator !=(Entity? left, Entity? right)
    {
        return !(left == right);
    }
}